package com.study.javaBasic.java_io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;

/**
 * @Name: ServerMainTest
 * @Description: java类作用描述
 * @Author: yn
 * @CreateDate: 2022/8/26 10:54
 * @Remark: 特殊说明
 * @Version: 1.0
 */
public class ServerMainTest {
	private final Selector selector;
	private final ServerSocketChannel serverSocketChannel;

	ServerMainTest() throws IOException {
		this.selector = Selector.open();
		this.serverSocketChannel = ServerSocketChannel.open();
		int PORT = 10001;
		serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
	}

	public void listen() {
		try {
			while (true) {
				int count = selector.select();
				if (count > 0) {
					Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
					while (iterator.hasNext()) {
						SelectionKey key = iterator.next();
						if (key.isAcceptable()) {
							SocketChannel sc = serverSocketChannel.accept();
							sc.configureBlocking(false);
							sc.register(selector, SelectionKey.OP_READ);
							System.out.println(sc.getRemoteAddress() + " accepted");
						}
						if (key.isReadable()) {
							readData(key);
						}
						iterator.remove();
					}
				} else {
					System.out.println("waiting....");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void readData(SelectionKey key) {
		SocketChannel channel = null;
		try {
			channel = (SocketChannel) key.channel();
			ByteBuffer buffer = ByteBuffer.allocate(1024);
			int count = channel.read(buffer);
			if (count > 0) {
				String msg = new String(buffer.array());
				System.out.println("form client:" + msg);
				reply(channel);
			}
		} catch (IOException e) {
			try {
				System.out.println(channel.getRemoteAddress() + " end..");
				key.cancel();
				channel.close();
			} catch (IOException e2) {
				e2.printStackTrace();
			}
		}
	}

	private void reply(SocketChannel channel) throws IOException {
		channel.write(ByteBuffer.wrap("> ok".getBytes(StandardCharsets.UTF_8)));
	}

	public static void main(String[] args) throws IOException {
		ServerMainTest server=new ServerMainTest();
		server.listen();
	}
}
